package myGUI;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

import Encryption.Aes;

import myVPN.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;

public class ServerGUI extends JFrame {

	private JPanel contentPane;
	private JTextField txt_IP;
	private JTextField txt_PortNum;
	private JTextField txt_SecretVal;
	
	private JButton btnStart;
	private JButton btnSend;
	private JButton btnContinue;
	
	private JTextArea txt_ToSend;
	private JTextArea txt_ToReceive;
	private JTextArea txt_ActualSent;
	private JTextArea txt_ActualReceived;
	
	private TCPServer tcpServer;
	private UpdateMessageTask updateTask;
	private JButton btnClear;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ServerGUI frame = new ServerGUI();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public ServerGUI() {		
		super("ServerGUI");
		
		tcpServer = new TCPServer();
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setTitle("VPN - Server");
		setBounds(100, 100, 780, 400);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
		
		JPanel panel = new JPanel();
		contentPane.add(panel, BorderLayout.CENTER);
		panel.setLayout(null);
		
		JLabel label = new JLabel("Server Mode");
		label.setBounds(10, 11, 740, 14);
		panel.add(label);
		
		JLabel label_1 = new JLabel("Server's IP address:");
		label_1.setBounds(10, 32, 168, 14);
		panel.add(label_1);
		
		JLabel label_2 = new JLabel("Port Number:");
		label_2.setBounds(10, 57, 168, 14);
		panel.add(label_2);
		
		JLabel label_3 = new JLabel("Shared Secret Value:");
		label_3.setBounds(10, 82, 168, 14);
		panel.add(label_3);
		
		JLabel label_4 = new JLabel("Data to be Sent");
		label_4.setBounds(10, 141, 118, 14);
		panel.add(label_4);
		
		JLabel label_5 = new JLabel("Data as Received");
		label_5.setBounds(10, 267, 118, 14);
		panel.add(label_5);
				
		String myIP_s= "";
		try {
			InetAddress myIP =InetAddress.getLocalHost();
			myIP_s = myIP.getHostAddress();
		} catch (UnknownHostException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
		//System.out.println("IP:"+thisIp.getHostAddress());
		txt_IP = new JTextField();
		txt_IP.setText(myIP_s);
		txt_IP.setEditable(false);
		txt_IP.setColumns(10);
		txt_IP.setBounds(190, 32, 298, 20);
		panel.add(txt_IP);
		
		txt_PortNum = new JTextField();
		txt_PortNum.setColumns(10);
		txt_PortNum.setBounds(190, 57, 298, 20);
		panel.add(txt_PortNum);
		
		txt_SecretVal = new JTextField();
		txt_SecretVal.setColumns(10);
		txt_SecretVal.setBounds(190, 82, 298, 20);
		panel.add(txt_SecretVal);
		
		btnStart = new JButton("Start");
		btnStart.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				(updateTask = new UpdateMessageTask()).execute();
			}
		});
		btnStart.setBounds(190, 113, 89, 23);
		panel.add(btnStart);
		
		txt_ToSend = new JTextArea();
		txt_ToSend.setBounds(190, 141, 298, 84);
		panel.add(txt_ToSend);
		
		btnSend = new JButton("Send");
		btnSend.setEnabled(false);
		btnSend.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				txt_ToReceive.setText("");
				txt_ActualReceived.setText("");
				
				try {
					tcpServer.setServerMessage(txt_ToSend.getText());
					tcpServer.sendMessage();
					txt_ActualSent.setText(tcpServer.getProcessedOut());
				
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		btnSend.setBounds(190, 236, 89, 23);
		panel.add(btnSend);
		
		txt_ToReceive = new JTextArea();
		txt_ToReceive.setEditable(false);
		txt_ToReceive.setBounds(190, 262, 298, 87);
		panel.add(txt_ToReceive);
		
		txt_ActualReceived = new JTextArea();
		txt_ActualReceived.setEditable(false);
		txt_ActualReceived.setBounds(498, 224, 252, 125);
		panel.add(txt_ActualReceived);
		
		JLabel label_6 = new JLabel("Actual Data Received:");
		label_6.setBounds(498, 199, 252, 14);
		panel.add(label_6);
		
		txt_ActualSent = new JTextArea();
		txt_ActualSent.setEditable(false);
		txt_ActualSent.setBounds(498, 63, 252, 125);
		panel.add(txt_ActualSent);
		
		JLabel label_7 = new JLabel("Actual Data Sent:");
		label_7.setBounds(498, 35, 153, 14);
		panel.add(label_7);
		
		btnContinue = new JButton("Continue");
		btnContinue.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				txt_ActualSent.setText("");
				txt_ToReceive.setText("");
				txt_ActualReceived.setText("");
				txt_ToSend.setText("");
				
				if (!tcpServer.isProtocolSuccess()){		

					try {
						
						if (tcpServer.getCurrSentIdx()==0){}
						else if (tcpServer.getCurrSentIdx()==1){
							tcpServer.doKeyExchangeOne();
							txt_ActualSent.setText(tcpServer.getProcessedOut());
							txt_ToSend.setText(tcpServer.getServerMessage());
						}
						else if (tcpServer.getCurrSentIdx()==2){}
						else if (tcpServer.getCurrSentIdx()==3){}
						
						
					} catch (Exception e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					
				}
			}
		});
		btnContinue.setBounds(661, 28, 89, 23);
		panel.add(btnContinue);
		
		btnClear = new JButton("Clear");
		btnClear.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				txt_ActualSent.setText("");
				txt_ToReceive.setText("");
				txt_ActualReceived.setText("");
				txt_ToSend.setText("");
			}
		});
		btnClear.setBounds(299, 113, 89, 23);
		panel.add(btnClear);
	}
	
	private class UpdateMessageTask extends SwingWorker<Void, String> {

		@Override
        protected Void doInBackground() {
			tcpServer.setProtocolSuccess(false);
			
			btnStart.setEnabled(false);
			
        	int portnum = Integer.parseInt(txt_PortNum.getText());
			tcpServer.setPortNum(portnum);
			String secretVal = txt_SecretVal.getText();
			tcpServer.setSecretVal(secretVal);
			try {
				tcpServer.initConnection();
				String from = "";
				while (true) {
					try {					
						tcpServer.startConnection();
						tcpServer.streamData();
						tcpServer.setCurrReceiveIdx(0);
						tcpServer.setCurrSentIdx(0);
						
						while (true){
							tcpServer.setProcessedIn("");
							tcpServer.readMessage();
							from = tcpServer.getClientMessage();
													
							if (from != null){
								if (tcpServer.getCurrReceiveIdx()==0)
								{
									String delims = "/";
									String[] tokens = from.split(delims);
									String Ra = tokens[0];
									tcpServer.setRaFromClient(Ra);
									tcpServer.setCurrSentIdx(1);
									tcpServer.setCurrReceiveIdx(1);
								}
								else if (tcpServer.getCurrReceiveIdx()==2)
								{
									//tcpServer.setProcessedIn(Aes.DecryptNoPadding(tcpServer.getClientMessage()));
									//tcpServer.setProcessedIn(tcpServer.getClientMessage());
									tcpServer.setEncrypted(tcpServer.getProcessedIn());
									
									String share = tcpServer.getSecretKey();
									if (!share.equalsIgnoreCase(tcpServer.getSecretVal())){
										txt_ToReceive.setText("Authentication failed");
										//tcpServer.closeConnection();
										break;
									}
									
									tcpServer.setCurrReceiveIdx(3);
									tcpServer.setCurrSentIdx(3);
									
									tcpServer.setProtocolSuccess(true);
									//txt_ToReceive.setText("connection established...");
									btnSend.setEnabled(true);
								}
								
								if (tcpServer.isProtocolSuccess()){
									//tcpServer.setProcessedIn(from);//should be value after decryption
									txt_ToReceive.setText(tcpServer.getProcessedIn());
									txt_ActualReceived.setText(tcpServer.getClientMessage());
								}
								else{
									if (tcpServer.getCurrReceiveIdx()<3){
										txt_ToReceive.setText(tcpServer.getProcessedIn());
										txt_ActualReceived.setText(tcpServer.getClientMessage());
									}										
								}
							}
						}

					} catch (Exception e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					publish(new String(from));
				}
			} catch (Exception e1) {
				// TODO: handle exception
				e1.printStackTrace();
			}
			return null;
        }
 
//        @Override
//        protected void process(List<String> strs) {
//        	String str = strs.get(strs.size() - 1);
//        	if (str != null){
//        		txt_ToReceive.setText(str);
//        	}
//            
//        }
    }

}
